<?php

$di = \application\units\Di::getInstance();

$params = [
    'admin_id' => $di->auth->id,
    'id'       => $di->request->params('id'),
    'role_id'  => $di->request->params('role_id'),
    'email'    => $di->request->params('email'),
    'nickname' => $di->request->params('nickname'),
    'username' => $di->request->params('username'),
    'password' => $di->request->params('password'),
    'avatar'   => $di->request->params('avatar', ''),
    'status'   => $di->request->params('status'),
];

$roleIds = is_string($params['role_id']) ? explode(',', $params['role_id']) : $params['role_id'];

if (false === \filter_var($params['email'], FILTER_VALIDATE_EMAIL)) throw new LogicException('邮箱格式错误');
if ('' == $params['nickname']) throw new LogicException('昵称不能为空');
if (0 == preg_match('/^[a-zA-Z][a-zA-Z0-9]{5,19}$/', $params['username'])) throw new LogicException('账号只能以字母开头，长度为6-20');
if ($params['password'] && strlen($params['password']) < 6) throw new LogicException('密码不能小于6位');
if (empty($roleIds)) throw new LogicException('角色组不能为空');
if (!in_array($params['status'], [0, 1])) throw new LogicException('状态参数不合法');

if ($params['admin_id']) {
    if ($params['admin_id'] == $params['id']) throw new LogicException("不能操作自己");
    $adminRoleIds = $di->auth->getRoleIdsByAdminId($params['id']);
    $authRoleIds  = $di->auth->getRoleIdsByAdminId($params['admin_id']);
    
    if (array_intersect($adminRoleIds, $authRoleIds)) {
        throw new LogicException('不能操作相同角色的用户');
    }
    $adminIds = $di->auth->getChildrenRoleAdminIds($params['admin_id'], false);
    
    if (!in_array($params['id'], $adminIds)) {
        throw new LogicException('不能操作其他角色组的用户');
    }
    
    if (array_diff($roleIds, $di->auth->getChildrenRoleIds($params['admin_id']))) {
        throw new LogicException('只能选择自己角色组下面的角色');
    }
}

$row = $di->db->find('select * from admin where id=:id', [
    'id' => $params['id'],
]);

if (!$row) throw new LogicException('未找到记录');

if ($row['email'] != $params['email']) {
    // 判断邮箱是否存在
    $hasEmail = $di->db->find('select * from admin where email=:email', [
        'email' => $params['email'],
    ]);
    if ($hasEmail) throw new LogicException('邮箱已存在');
}

if ($row['username'] != $params['username']) {
    // 判断账号是否存在
    $hasUsername = $di->db->find('select * from admin where username=:username', [
        'username' => $params['username'],
    ]);
    if ($hasUsername) throw new LogicException('账号已存在');
}
if ($params['password']) { // 空表示不修改密码
    $row['salt']     = substr(md5(random_bytes(32)), 0, 6);
    $row['password'] = md5(md5($params['password']) . $row['salt']);
    $row['token']    = ''; // 修改密码需要重新登录
}

try {
    
    $di->db->beginTransaction();
    
    $stat = $di->db->execute('update admin set username=:username, email=:email, token=:token, password=:password,
                 salt=:salt, nickname=:nickname, avatar=:avatar, status=:status, update_time=:update_time where id=:id', [
        'username'    => $params['username'],
        'email'       => $params['email'],
        'nickname'    => $params['nickname'],
        'avatar'      => $params['avatar'],
        'status'      => $params['status'],
        'token'       => $row['token'],
        'password'    => $row['password'],
        'salt'        => $row['salt'],
        'id'          => $row['id'],
        'update_time' => date('Y-m-d H:i:s'),
    ]);
    
    if ($stat->rowCount() <= 0) throw new PDOException('操作失败');
    
    $hasRoleIds = array_column($di->db->query('select role_id from admin_role_access where admin_id=:admin_id', [
        'admin_id' => $row['id'],
    ]), 'role_id');
    
    $addRoleIds = array_diff($roleIds, $hasRoleIds);
    $delRoleIds = array_diff($hasRoleIds, $roleIds);
    
    if ($delRoleIds) {
        $stat = $di->db->execute('delete from admin_role_access where admin_id=:admin_id and role_id in (:role_id)', [
            'admin_id' => $row['id'],
            'role_id'  => $delRoleIds,
        ]);
        if ($stat->rowCount() <= 0) throw new PDOException('操作失败');
    }
    
    // 添加管理员角色
    foreach ($addRoleIds as $roleId) {
        $stat = $di->db->execute('insert into admin_role_access(admin_id, role_id, update_time, create_time)
                          values (:admin_id, :role_id, :update_time, :create_time)', [
            'admin_id'    => $row['id'],
            'role_id'     => $roleId,
            'update_time' => date('Y-m-d H:i:s'),
            'create_time' => date('Y-m-d H:i:s'),
        ]);
        if ($stat->rowCount() <= 0) throw new PDOException('操作失败');
    }
    
    $di->db->commit();
} catch (Exception $e) {
    $di->db->rollback();
    throw $e;
}

return [];